/****************************************************************
irrEventManager
Copyright (C) 2007-2008 Keith Holbrook
This file is part of "irrEventManager".
For conditions of distribution and use, see copyright notice in irrEventManagerr.h

*****************************************************************/

#ifndef CEVENT_EX_H
#define CEVENT_EX_H


#include "IEventEx.h"
#include "irrarray.h"
#include "..\Debug.h"


namespace irr
{
#ifdef _DEBUG

    const char* const  eventTypes[] =
    {
        "GUI_EVENT",
        "MOUSE_INPUT_EVENT",
        "KEY_INPUT_EVENT",
        "JOYSTICK_INPUT_EVENT",
        "LOG_TEXT_EVENT",
        "USER_EVENT"
    };

    const char* const  guiEventTypes[]=
    {
        "ELEMENT_FOCUS_LOST",
        "ELEMENT_FOCUSED","ELEMENT_HOVERED","ELEMENT_LEFT",
        "ELEMENT_CLOSED","BUTTON_CLICKED",
        "SCROLL_BAR_CHANGED","CHECKBOX_CHANGED","LISTBOX_CHANGED",
        "LISTBOX_SELECTED_AGAIN","FILE_SELECTED",
        "FILE_CHOOSE_DIALOG_CANCELLED","MESSAGEBOX_YES","MESSAGEBOX_NO",
        "MESSAGEBOX_OK","MESSAGEBOX_CANCEL","EDITBOX_ENTER",
        "TAB_CHANGED","MENU_ITEM_SELECTED","COMBO_BOX_CHANGED","SPINBOX_CHANGED","TABLE_CHANGED",
        "TABLE_HEADER_CHANGED","TABLE_SELECTED_AGAIN"
    };

#endif
    class CEventEx : public virtual IEventEx
    {

    private:



        CEventEx(CEventEx&);
        CEventEx & operator = (const CEventEx&);

    protected:
        // EEVENT_TYPE type;
        s32 ids;
        core::array<IEventRecEx*>receivers;

        ///I have decided not to reoder-resize the receivers array
        ///as new ones are added they will fill in the empty slots

    public:

        CEventEx(s32 id):ids(id)
        {
        }

        virtual ~CEventEx()
        {
            removeAll();
        }

        virtual u32 getReceiverCount();

        virtual s32 getId()
        {
            return ++ids;
        }

        virtual void setId(s32 id)
        {
            ids=id;
        }

        virtual EEVENT_TYPE getType()=0;

        virtual gui::EGUI_EVENT_TYPE getGuiEventType()
        {
            return gui::EGET_ELEMENT_FOCUS_LOST;
        }

        virtual void removeAll();

        //!add a new receiver to the list called on the corresponding  event
        virtual bool add(IEventRecEx* r,s32 item=-1);

        //!remove receiver
        virtual  void remove(IEventRecEx* r);

        virtual void removeByCaller(void* caller);

        virtual void removeByData(void* dat);

        virtual void removeByObject(void* obj);

        virtual void removeById(s32 id);

        virtual bool doEvent(const SEvent& ev);

    };

    class CKeyEventEx : public CEventEx
    {
    public:
        CKeyEventEx(s32 startId=999):CEventEx(startId)
        {
#ifdef _DEBUG
            DEBUG_PRINT("%s created\n",eventTypes[EET_KEY_INPUT_EVENT]);
        }
        ~CKeyEventEx()
        {
            DEBUG_PRINT("%s , %i Receivers destroyed\n",eventTypes[getType()],getReceiverCount());
        }
#else
        }
#endif


    virtual EEVENT_TYPE getType()
    {
        return EET_KEY_INPUT_EVENT;
    }
};

class CMouseEventEx : public CEventEx
{
public:
    CMouseEventEx(s32 startId=999):CEventEx(startId)
    {
#ifdef _DEBUG
            DEBUG_PRINT("%s created\n",eventTypes[EET_MOUSE_INPUT_EVENT]);
        }
        ~CMouseEventEx()
        {
            DEBUG_PRINT("%s , %i Receivers destroyed\n",eventTypes[getType()],getReceiverCount());
        }
#else

        }
#endif

    virtual EEVENT_TYPE getType()
    {
        return EET_MOUSE_INPUT_EVENT;
    }
};

class CUserEventEx : public CEventEx
{
public:
    CUserEventEx(s32 startId=999):CEventEx(startId)
    {
#ifdef _DEBUG
            DEBUG_PRINT("%s created\n",eventTypes[EET_USER_EVENT]);
        }
        ~CUserEventEx()
        {
            DEBUG_PRINT("%s , %i Receivers destroyed\n",eventTypes[getType()],getReceiverCount());
        }
#else

        }
#endif
    virtual EEVENT_TYPE getType()
    {
        return EET_USER_EVENT;
    }
};

class CLogEventEx : public CEventEx
{
public:
    CLogEventEx(s32 startId=999):CEventEx(startId)
    {
#ifdef _DEBUG
            DEBUG_PRINT("%s created\n",eventTypes[EET_LOG_TEXT_EVENT]);
        }
        ~CLogEventEx()
        {
            DEBUG_PRINT("%s , %i Receivers destroyed\n",eventTypes[getType()],getReceiverCount());
        }
#else

        }
#endif
    virtual EEVENT_TYPE getType()
    {
        return EET_LOG_TEXT_EVENT;
    }
};


class CJoyEventEx : public CEventEx
{
public:
    CJoyEventEx(s32 startId=999):CEventEx(startId)
    {
#ifdef _DEBUG
            DEBUG_PRINT("%s created\n",eventTypes[EET_JOYSTICK_INPUT_EVENT]);
        }
        ~CJoyEventEx()
        {
            DEBUG_PRINT("%s , %i Receivers destroyed\n",eventTypes[getType()],getReceiverCount());
        }
#else

        }
#endif
    virtual EEVENT_TYPE getType()
    {
        return EET_JOYSTICK_INPUT_EVENT;
    }
};


class CGuiEventEx : public CEventEx
{

protected:
    gui::EGUI_EVENT_TYPE guiEventType;
public:

    CGuiEventEx( gui::EGUI_EVENT_TYPE t,s32 startId=999):CEventEx(startId),guiEventType(t)
  {
#ifdef _DEBUG
           DEBUG_PRINT("GUIEVENT %s  created\n",guiEventTypes[t]);
        }
        ~CGuiEventEx()
        {
            DEBUG_PRINT("%s , %i Receivers destroyed\n",guiEventTypes[guiEventType],getReceiverCount());
        }
#else

        }
#endif

    virtual EEVENT_TYPE getType()
    {
        return EET_GUI_EVENT;
    }

    //!add a new receiver to the list called for this event
    virtual bool add(IEventRecEx* r,s32 item=-1);

    virtual bool doEvent(const SEvent& ev);

    virtual gui::EGUI_EVENT_TYPE getGuiEventType()
    {
        return guiEventType;
    }

};

}

#endif //


